package com.dongdongkeji.base.api;

import com.dongdongkeji.base.bean.dto.BaseDTO;
import com.dongdongkeji.base.bean.dto.BaseListDTO;
import com.dongdongkeji.base.constant.BaseApiConstants;
import com.dongdongkeji.base.exceptions.ApiException;
import com.dongdongkeji.base.interfaces.Mapper;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by CJ on 2016/10/27 0027.
 */
public class ApiExecutor {

    /**
     * 使用RxJava异步执行网络请求（返回值为空）
     *
     * @param observable
     * @param observer
     * @param <T>
     */
    public static <T extends BaseDTO> void executeNone(Observable<T> observable, Observer observer) {
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Function<T, String>() {
                    @Override
                    public String apply(@NonNull T t) throws Exception {
                        if (t.getCode() != BaseApiConstants.SUCCESS) {
                            throw new ApiException(t.getCode(), t.getMsg());
                        }
                        return "";
                    }
                })
                .subscribe(observer);
    }

    /**
     * 使用RxJava异步执行网络请求（返回值为对象）
     *
     * @param observable
     * @param observer
     * @param <T>
     * @param <R>
     */
    public static <T extends BaseDTO<K>, K extends Mapper<R>, R> void execute(Observable<T> observable, Observer<R> observer) {
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Function<T, R>() {
                    @Override
                    public R apply(@NonNull T t) throws Exception {
                        if (t.getCode() != BaseApiConstants.SUCCESS) {
                            throw new ApiException(t.getCode(), t.getMsg());
                        }
                        return t.getData().transform();
                    }
                })
                .subscribe(observer);
    }

    /**
     * 使用RxJava异步执行网络请求（返回值为List）
     *
     * @param observable
     * @param observer
     * @param <T>
     * @param <R>
     */
    public static <T extends BaseListDTO<K>, K extends Mapper<R>, R> void executeList(Observable<T> observable, Observer<List<R>> observer) {
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Function<T, List<R>>() {
                    @Override
                    public List<R> apply(@NonNull T t) throws Exception {
                        if (t.getCode() != BaseApiConstants.SUCCESS) {
                            throw new ApiException(t.getCode(), t.getMsg());
                        }
                        List<K> list = t.getData();
                        List<R> result = new ArrayList<>();
                        if (list != null) {
                            for (K k : list) {
                                result.add(k.transform());
                            }
                        }
                        return result;
                    }
                })
                .subscribe(observer);
    }
}